package org.zachary.imitation.raft;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zachary.utils.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 封装集群中各个节点的信息
 *
 * Created by guozhaokun on 2024/8/30 16:10.
 */
public class Configuration {
	private Logger logger = LoggerFactory.getLogger(Configuration.class);

	/** 集群中的每个节点的信息被包装为 Peer 对象，这里存放集群中的所有节点信息 */
	private List<PeerId> peers = new ArrayList<>();

	public Configuration() {

	}

	public Configuration(Iterable<PeerId> peers) {
		for (PeerId peerId : peers) {
			this.peers.add(peerId);
		}
	}

	public void reset() {
		this.peers.clear();
	}

	public List<PeerId> getPeers() {
		return this.peers;
	}

	public void setPeers(final List<PeerId> peers) {
		this.peers.clear();
		this.peers.addAll(peers);
	}

	public boolean addPeer(final PeerId peer) {
		return this.peers.add(peer);
	}

	/** 该方法是本类中最重要的方法，会解析用户传递到 main 方法中的参数（比如 127.0.0.1:8081,127.0.0.1:8082,127.0.0.1:8083），解析为集群中的节点信息 */
	public boolean parse(final String conf) {
		if (StringUtils.isBlank(conf)) {
			return false;
		}
		reset();
		final String[] peerStrs = conf.split(",");
		for (String peerStr : peerStrs) {
			// 创建一个 PeerId 对象用来封装每一个节点的信息
			final PeerId peer = new PeerId();
			if (peer.parse(peerStr)) {
				addPeer(peer);
			} else {
				logger.error("Fail to parse peer {} in {}, ignore it.", peerStr, conf);
			}
		}
		return true;
	}

	/** 集群中是否包含指定的 PeerId 节点 */
	public boolean contains(PeerId peerId) {
		return peers.contains(peerId);
	}
}
